package com.yebxxx.config;




import com.yebxxx.server.pojo.Admin;
import com.yebxxx.server.service.IAdminService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.config.annotation.ObjectPostProcessor;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
public class security extends WebSecurityConfigurerAdapter {
    @Lazy
    @Autowired
    private IAdminService iAdminService;
    @Autowired
    private RestFullAccessDeniedHandler restFullAccessDeniedHandler;
    @Autowired
    private  RestsAuthorizationPoint restsAuthorizationPoint;
    @Autowired
    private  CustomFilter customFilter;
    @Autowired
    private  CustomUrlDecisionManager customUrlDecisionManager;
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
         auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder());
    }
   //放行swagger
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers(
                "/login",
                "/logout",
                "/css/**",
                "/js/**",
                "/index.html",
                "/doc.html",
                "/webjars/**",
                "/swagger-resources/**",
                "/v2/api-docs/**",
                "/captcha",
                "/ws/**",
                "/sockjs-node/",
                "/system/cfg/menu"
        );
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
       http.csrf()
               .disable()
               //基于token不需要session
               .sessionManagement()
               .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
               .and()
               .authorizeRequests()
//               .antMatchers("/login","logout")
//               .permitAll()
               .anyRequest()
               .authenticated()
               //动态权限配置
               .withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {
                   @Override
                   public <O extends FilterSecurityInterceptor> O postProcess(O o) {
                       o.setAccessDecisionManager(customUrlDecisionManager);
                       o.setSecurityMetadataSource(customFilter);
                       return o;
                   }
               })
               .and()
               .headers()
               .cacheControl();
       //添加过滤器
       http.addFilterBefore(jetAuthencationFilter(), UsernamePasswordAuthenticationFilter.class);
       //添加自定义未登录授权和登陆结果返回
        http.exceptionHandling()
                .accessDeniedHandler(restFullAccessDeniedHandler)
                .authenticationEntryPoint(restsAuthorizationPoint);
    }

    @Override
    @Bean
    public UserDetailsService userDetailsService(){
        return  username ->{
            Admin admin=iAdminService.getAdminByUsername(username);
            if(null!=admin){
                admin.setRoles(iAdminService.getRoles(admin.getId()));
                return  admin;
            }
           throw  new UsernameNotFoundException("用户名或密码不正确");
        };
    }

    @Bean
    PasswordEncoder passwordEncoder(){
        return  new BCryptPasswordEncoder();
    }
@Bean
 public   JwtFilter jetAuthencationFilter(){
      return  new JwtFilter();
}
}
